package com.baijiayun.live.ui.setting;

import android_serialport_api.DeviceInfo;

import com.baijiayun.live.ui.LiveSDKWithUI;
import com.baijiayun.live.ui.activity.LiveRoomRouterListener;
import com.baijiayun.live.ui.menu.rightmenu.RightMenuContract;
import com.baijiayun.livecore.context.LPConstants;
import com.baijiayun.livecore.context.LPError;
import com.baijiayun.livecore.context.LiveRoom;
import com.baijiayun.livecore.models.LPBleDevice;
import com.baijiayun.livecore.models.launch.LPEnterRoomNative;
import com.baijiayun.livecore.ppt.PPTView;
import com.baijiayun.livecore.wrapper.LPPlayer;
import com.baijiayun.livecore.wrapper.LPRecorder;
import com.baijiayun.liveuibase.utils.RxUtils;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static com.baijiayun.live.ui.utils.Precondition.checkNotNull;

/**
 * @author wubanglin
 */
public class SettingPresenter implements SettingContract.Presenter {

    private SettingContract.View view;
    private LiveRoomRouterListener routerListener;
    private LiveRoom liveRoom;
    private LPRecorder recorder;
    private LPPlayer player;
    private Disposable subscriptionOfForbidAllChat, subscriptionOfMic, subscriptionOfCamera, subscriptionOfForbidRaiseHand,
            subscriptionOfUpLinkType, subscriptionOfDownLinkType, subscriptionOfForbidAllAudio, subscriptionOfChangePPT;
    private Disposable disposableOfMirrorModeSwitch;
    private ArrayList<String> tcpCdnTag;

    public SettingPresenter(SettingContract.View view) {
        this.view = view;
    }

    @Override
    public void setRouter(LiveRoomRouterListener liveRoomRouterListener) {
        this.routerListener = liveRoomRouterListener;
        recorder = routerListener.getLiveRoom().getRecorder();
        player = routerListener.getLiveRoom().getPlayer();
        liveRoom = routerListener.getLiveRoom();
    }

    @Override
    public void subscribe() {
        checkNotNull(routerListener);
        if (!liveRoom.isClassStarted()) {
            view.setMicEnable(false);
            view.setCameraEnable(false);
            view.setForbidAllAudioEnable(false);
            view.setForbiddenEnable(false);
            view.setForbidRaiseHandEnable(false);
            view.setRemarkSettingEnable(true);
            view.setPPTShowTypeEnable(true);
            view.setPPTViewTypeEnable(true);
            view.setDefinitionEnable(false);
            view.setWhichCameraEnable(false);
            view.setUpLinkEnable(false);
            view.setDownLinkEnable(false);
            view.setAudioEnable(false);
            view.setChangePPTEnable(false);
        } else {
            view.setMicEnable(true);
            view.setCameraEnable(true);
            view.setForbidAllAudioEnable(true);
            view.setForbiddenEnable(true);
            view.setForbidRaiseHandEnable(true);
            view.setRemarkSettingEnable(true);
            view.setPPTShowTypeEnable(true);
            view.setPPTViewTypeEnable(true);
            view.setDefinitionEnable(true);
            view.setWhichCameraEnable(true);
            view.setUpLinkEnable(true);
            view.setDownLinkEnable(true);
            view.setAudioEnable(true);
            view.setChangePPTEnable(true);
        }
        if (liveRoom.getSpeakQueueVM().isReplacedUser()) {
            view.setDefinitionEnable(false);
            view.setWhichCameraEnable(false);
        }
        if (!isTeacherOrAssistant()) {
            view.showStudentsHandsUp(routerListener.getSpeakApplyStatus() == RightMenuContract.STUDENT_SPEAK_APPLY_SPEAKING);
            view.hidePPTMenu();
        }
        if (!routerListener.isTeacherOrAssistant() || liveRoom.getTemplateType() == LPConstants.TemplateType.VIDEO) {
            view.hidePPTChangeMenu();
        }
        if (isUseWebRTC()) {
            view.showUpLinkType(true);
            view.showDownLinkType(true);
            view.setUpLinkEnable(false);
            view.setDownLinkEnable(false);
        } else {
            view.showUpLinkType(recorder.getLinkType() == LPConstants.LPLinkType.TCP);
            view.showDownLinkType(player.getLinkType() == LPConstants.LPLinkType.TCP);
        }
        if (routerListener.getPPTView().isHavePPT()) {
            if (routerListener.getPPTView().didRoomContainsAnimPPT()) {
                if (routerListener.getPPTView().didRoomContainsH5PPT()) {
                    view.showPPTViewType(true);
                    view.setPPTViewTypeEnable(false);
                } else {
                    view.showPPTViewType(routerListener.getPPTView().isAnimPPTEnable());
                }
            } else {
                view.showPPTViewType(false);
                view.setPPTViewTypeEnable(false);
            }
        } else {
            view.showPPTViewNoPPT();
            view.setPPTViewTypeEnable(false);
        }
        view.showMic(recorder.isAudioAttached());
        view.showCamera(recorder.isVideoAttached());
        view.showChangePPTEnable(!liveRoom.getStudentSwitchPPTState());

        view.showWhichCamera(recorder.getCameraOrientation());
        view.showCameraSwitchStatus(recorder.isVideoAttached());
        view.showWhichCamera(recorder.getCameraOrientation());
        view.showForbidRaiseHand(liveRoom.getForbidRaiseHandStatus());
        view.showForbidAllAudio(liveRoom.getForbidAllAudioStatus());
        if (liveRoom.getPartnerConfig().PPTAnimationDisable == 0) {
            view.hidePPTShownType();
        }
        view.showAudio(LiveSDKWithUI.isAudioBackOpen);
        view.showForbidden(liveRoom.getForbidStatus(LPConstants.LPForbidChatType.TYPE_GROUP));
        if (isGroup()) {
            view.setForbiddenEnable(!liveRoom.getForbidStatus(LPConstants.LPForbidChatType.TYPE_ALL));
        }
        subscriptionOfForbidAllChat = liveRoom.getObservableOfForbidAllChatStatus().observeOn(AndroidSchedulers.mainThread())
                .subscribe(result -> {
                    //分组被全体禁言则不能操作且学生是禁言状态
                    if (result.type == LPConstants.LPForbidChatType.TYPE_ALL && liveRoom.getCurrentUser().getGroup() != 0) {
                        view.setForbiddenEnable(!result.isForbid);
                    }
                    view.showForbidden(result.isForbid);
                });
        subscriptionOfMic = liveRoom.getRecorder().getObservableOfMicOn().observeOn(AndroidSchedulers.mainThread())
                .subscribe(aBoolean -> view.showMic(aBoolean));

        subscriptionOfCamera = liveRoom.getRecorder().getObservableOfCameraOn().observeOn(AndroidSchedulers.mainThread())
                .subscribe(aBoolean -> {
                    view.setDefinitionEnable(!liveRoom.getSpeakQueueVM().isReplacedUser());
                    view.setWhichCameraEnable(!liveRoom.getSpeakQueueVM().isReplacedUser());
                    view.showCamera(aBoolean);
                });
        subscriptionOfForbidRaiseHand = liveRoom.getObservableOfForbidRaiseHand().observeOn(AndroidSchedulers.mainThread())
                .subscribe(aBoolean ->
                        view.showForbidRaiseHand(aBoolean)
                );

        subscriptionOfForbidAllAudio = liveRoom.getObservableOfForbidAllAudioStatus()
                .subscribe(aBoolean -> {
                    if (liveRoom.isTeacherOrAssistant()) {
                        //老师或助教，同步静音状态
                        view.showForbidAllAudio(aBoolean);
                        return;
                    }
                    //学生
                    if (aBoolean && recorder.isAudioAttached()) {
                        //静音
                        recorder.detachAudio();
                    }
                });
        subscriptionOfDownLinkType = liveRoom.getPlayer().getObservableOfLinkType().observeOn(AndroidSchedulers.mainThread())
                .subscribe(lpLinkType -> view.showDownLinkType(lpLinkType == LPConstants.LPLinkType.TCP));

        subscriptionOfUpLinkType = liveRoom.getRecorder().getObservableOfLinkType().observeOn(AndroidSchedulers.mainThread())
                .subscribe(lpLinkType -> {
                    view.showUpLinkType(lpLinkType == LPConstants.LPLinkType.TCP);
                });

        subscriptionOfChangePPT = liveRoom.getObservableOfForbidStudentSwitchPPT()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(isEnable -> {
                    view.showChangePPTEnable(!isEnable);
                });

        disposableOfMirrorModeSwitch = liveRoom.getSpeakQueueVM().getObservableOfMirrorMode()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(lpMirrorModeModel -> {
                    view.onMirrorModeChange(lpMirrorModeModel, liveRoom.getSpeakQueueVM().getHorizontalMirrorModeSet(), liveRoom.getSpeakQueueVM().getVerticalMirrorModeSet());
                });

        view.onMirrorModeChange(null, liveRoom.getSpeakQueueVM().getHorizontalMirrorModeSet(), liveRoom.getSpeakQueueVM().getVerticalMirrorModeSet());

        try {
            tcpCdnTag = (ArrayList<String>) liveRoom.getPartnerConfig().msConfig.get("live_stream_cdn_list");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void unSubscribe() {
        RxUtils.dispose(subscriptionOfForbidAllChat);
        RxUtils.dispose(subscriptionOfMic);
        RxUtils.dispose(subscriptionOfCamera);
        RxUtils.dispose(subscriptionOfForbidRaiseHand);
        RxUtils.dispose(subscriptionOfUpLinkType);
        RxUtils.dispose(subscriptionOfDownLinkType);
        RxUtils.dispose(subscriptionOfForbidAllAudio);
        RxUtils.dispose(disposableOfMirrorModeSwitch);
        RxUtils.dispose(subscriptionOfChangePPT);
    }

    @Override
    public void destroy() {
        routerListener = null;
    }

    @Override
    public String getRoomId() {
        return String.valueOf(routerListener.getLiveRoom().getRoomId());
    }

    @Override
    public List<LPBleDevice> getRecentBleDevices() {
        return liveRoom.getZXYBVM().getRecentBleDevices();
    }

    @Override
    public DeviceInfo getConnectedDevice() {
        return liveRoom.getZXYBVM().getConnectedDevice();
    }

    @Override
    public void showBleDialog() {
        routerListener.showBleDialog();
    }

    @Override
    public void changeCamera() {
        if (routerListener.getLiveRoom().getRoomMediaType() == LPConstants.LPMediaType.Audio) {
            return;
        }
        switch (routerListener.getLiveRoom().getCurrentUser().getType()) {
            case Teacher:
            case Assistant:
                if (!recorder.isPublishing()) {
                    recorder.publish();
                }
                if (recorder.isVideoAttached()) {
                    view.showCameraSwitchStatus(!recorder.isVideoAttached());
                    routerListener.detachLocalVideo();
                } else {
                    view.showCameraSwitchStatus(!recorder.isVideoAttached());
                    routerListener.attachLocalVideo();
                }
                break;
            case Student:
                if (routerListener.getSpeakApplyStatus() != RightMenuContract.STUDENT_SPEAK_APPLY_SPEAKING) {
                    return;
                }
                if (recorder.isVideoAttached()) {
                    routerListener.detachLocalVideo();
                } else {
                    routerListener.attachLocalVideo();
                }
                view.showCameraSwitchStatus(recorder.isVideoAttached());
                break;
            case Visitor:
                break;
            default:
                break;
        }
    }

    @Override
    public boolean isReplaceCamera() {
        return liveRoom != null && liveRoom.getSpeakQueueVM().isReplacedUser();
    }

    @Override
    public void changeMic() {
        switch (routerListener.getLiveRoom().getCurrentUser().getType()) {
            case Teacher:
            case Assistant:
                if (!recorder.isPublishing()) {
                    recorder.publish();
                }
                if (recorder.isAudioAttached()) {
                    recorder.detachAudio();
                } else {
                    routerListener.attachLocalAudio();
                }
                break;
            case Student:
                if (routerListener.getSpeakApplyStatus() != RightMenuContract.STUDENT_SPEAK_APPLY_SPEAKING) {
                    return;
                }
                if (recorder.isAudioAttached()) {
                    recorder.detachAudio();
                } else {
                    routerListener.attachLocalAudio();
                }
                break;
            case Visitor:
                view.showVisitorFail();
                break;
            default:
                break;
        }
    }

    @Override
    public void switchAudio() {
        LiveSDKWithUI.isAudioBackOpen = !LiveSDKWithUI.isAudioBackOpen;
        view.showAudio(LiveSDKWithUI.isAudioBackOpen);
    }

    @Override
    public void setRemarksEnable(boolean isEnable) {
        routerListener.setRemarksEnable(isEnable);
    }

    @Override
    public void switchForbidAllAudio(boolean isForbid) {
        liveRoom.requestForbidAllAudio(isForbid);
    }

    @Override
    public boolean switchForbidStatus() {
        if (!canSwitchForbid()) {
            view.showSwitchForbid();
            return false;
        }
        liveRoom.requestForbidAllChat(!liveRoom.getForbidStatus(LPConstants.LPForbidChatType.TYPE_GROUP));
        return true;
    }

    private boolean canSwitchForbid() {
        return !(liveRoom.getCurrentUser().getType() == LPConstants.LPUserType.Assistant && liveRoom.getAdminAuth() != null
                && !liveRoom.getAdminAuth().forbidAndKick);
    }

    @Override
    public void switchForbidRaiseHand() {
        liveRoom.requestForbidRaiseHand(!liveRoom.getForbidRaiseHandStatus());
    }

    @Override
    public void setBeautyLevel(float beautyLevel) {
        liveRoom.getRecorder().setBeautyLevel(beautyLevel);
    }

    @Override
    public float getBeautyLevel() {
        return liveRoom.getRecorder().getBeautyLevel();
    }

    @Override
    public void setWhitenessLevel(float whitenessLevel) {
        liveRoom.getRecorder().setWhitenessLevel(whitenessLevel);
    }

    @Override
    public float getWhitenessLevel() {
        return liveRoom.getRecorder().getWhitenessLevel();
    }

    @Override
    public int getWebrtcType() {
        return liveRoom.getRoomInfo().webRTCType;
    }

    @Override
    public boolean isVideoAttached() {
        return liveRoom != null && liveRoom.getRecorder().isVideoAttached();
    }

    @Override
    public boolean isTeacherOrAssistant() {
        return routerListener.isTeacherOrAssistant() || routerListener.isGroupTeacherOrAssistant();
    }

    @Override
    public boolean isUseWebRTC() {
        return routerListener.getLiveRoom().isUseWebRTC();
    }

    @Override
    public void setPPTFullScreen() {
        routerListener.setPPTShowType(LPConstants.LPPPTShowWay.SHOW_FULL_SCREEN);
    }

    @Override
    public void setPPTOverspread() {
        routerListener.setPPTShowType(LPConstants.LPPPTShowWay.SHOW_COVERED);
    }

    @Override
    public boolean isGroup() {
        return routerListener.getLiveRoom().getCurrentUser().getGroup() != 0;
    }

    @Override
    public void switchChangePPTEnable(int checkedPosition) {
        if (routerListener.getLiveRoom().hasH5PPTAuth() && checkedPosition == 1) {
            view.onChangePPTForbidFailed();
            routerListener.getLiveRoom().requestH5PPTAuth(false);
        }
        routerListener.getLiveRoom().requestForbidStudentSwitchPPT(checkedPosition == 1);
    }

    @Override
    public void switchAllHorizonMirrorMode(boolean on) {
        liveRoom.getSpeakQueueVM().requestMirrorModeAllSwitch(on, liveRoom.getSpeakQueueVM().getVerticalMirrorModeSet().contains(liveRoom.getCurrentUser().getNumber()));
    }

    @Override
    public void switchAllVerticalMirrorMode(boolean on) {
        liveRoom.getSpeakQueueVM().requestMirrorModeAllSwitch(liveRoom.getSpeakQueueVM().getHorizontalMirrorModeSet().contains(liveRoom.getCurrentUser().getNumber()), on);
    }

    @Override
    public void switchCamera(boolean asFront) {
        if (recorder != null && asFront != recorder.getCameraOrientation()) {
            recorder.switchCamera();
            view.showWhichCamera(recorder.getCameraOrientation());
        }
    }

    @Override
    public boolean isClassStart() {
        return liveRoom.isClassStarted();
    }

    @Override
    public boolean getCameraOrientation() {
        return recorder.getCameraOrientation();
    }

    @Override
    public boolean isAudioAttached() {
        return liveRoom != null && liveRoom.getRecorder().isAudioAttached();
    }

    @Override
    public int getSpeakApplyStatus() {
        return routerListener.getSpeakApplyStatus();
    }

    @Override
    public LPConstants.LPLinkType getLinkType() {
        return recorder.getLinkType();
    }

    @Override
    public boolean getForbidRaiseHandStatus() {
        return liveRoom != null && liveRoom.getForbidRaiseHandStatus();
    }

    @Override
    public boolean getForbidAllAudioStatus() {
        return liveRoom != null && liveRoom.getForbidAllAudioStatus();
    }

    @Override
    public boolean getForbidStatus(LPConstants.LPForbidChatType typeGroup) {
        return liveRoom != null && liveRoom.getForbidStatus(typeGroup);
    }

    @Override
    public PPTView getPPTView() {
        return routerListener.getPPTView();
    }

    @Override
    public boolean getStudentSwitchPPTState() {
        return liveRoom != null && liveRoom.getStudentSwitchPPTState();
    }

    @Override
    public LPEnterRoomNative.LPPartnerConfig getPartnerConfig() {
        return liveRoom.getPartnerConfig();
    }

    @Override
    public Set<String> getHorizontalMirrorModeSet() {
        return liveRoom.getSpeakQueueVM().getHorizontalMirrorModeSet();
    }

    @Override
    public Set<String> getVerticalMirrorModeSet() {
        return liveRoom.getSpeakQueueVM().getVerticalMirrorModeSet();
    }

    @Override
    public LPConstants.LPResolutionType getVideoDefinition() {
        return liveRoom.getRecorder().getVideoDefinition();
    }

    @Override
    public LPError setCaptureVideoDefinition(LPConstants.LPResolutionType resolutionType) {
        return liveRoom.getRecorder().setCaptureVideoDefinition(resolutionType);
    }

    @Override
    public LPConstants.TemplateType getTemplateType() {
        return liveRoom.getTemplateType();
    }

    @Override
    public void setPPTViewAnim() {
        if (!routerListener.enableAnimPPTView(true)) {
            view.showSwitchPPTFail();
        }
    }

    @Override
    public void setPPTViewStatic() {
        if (!routerListener.enableAnimPPTView(false)) {
            view.showSwitchPPTFail();
        }
    }

    @Override
    public int getCDNCount() {
        return tcpCdnTag == null ? 0 : tcpCdnTag.size();
    }

    @Override
    public void setUpCDNLink(int order) {
        if (liveRoom.getRecorder().setTcpWithCdn(tcpCdnTag.get(order))) {
            view.showUpLinkType(true);
        } else {
            view.showSwitchLinkTypeError();
        }
    }

    @Override
    public void setUpLinkTCP() {
        if (recorder.setLinkType(LPConstants.LPLinkType.TCP)) {
            view.showUpLinkType(true);
        } else {
            view.showSwitchLinkTypeError();
        }
    }

    @Override
    public void setUpLinkUDP() {
        if (recorder.setLinkType(LPConstants.LPLinkType.UDP)) {
            view.showUpLinkType(false);
        } else {
            view.showSwitchLinkTypeError();
        }
    }

    @Override
    public void setDownLinkTCP() {
        if (player.setLinkType(LPConstants.LPLinkType.TCP)) {
            view.showDownLinkType(true);
        } else {
            view.showSwitchLinkTypeError();
        }
    }

    @Override
    public void setDownLinkUDP() {
        if (player.setLinkType(LPConstants.LPLinkType.UDP)) {
            view.showDownLinkType(false);
        } else {
            view.showSwitchLinkTypeError();
        }
    }

    @Override
    public void setDownCDNLink(int order) {
        String tcpCdn = "";
        //-1为自动模式，设置preferCDN=""
        if(order >= 0 && order < tcpCdnTag.size()){
            tcpCdn = tcpCdnTag.get(order);
        }
        if(liveRoom.getPlayer().setLinkTypeTcpWithCdn(tcpCdn)){
            view.showDownLinkType(true);
        }else{
            view.showSwitchLinkTypeError();
        }
    }

    @Override
    public LPConstants.LPRoomType getRoomType() {
        return liveRoom.getRoomType();
    }
}
